package cmbchina;

import com.jcraft.jsch.*;
import org.slf4j.*;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * Desc:
 * User: chen,shu-bin
 * Date: 2014/12/2
 * Ver.: 1.0
 */
public class JschUtil {


    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(JschUtil.class);
    private String charset = "UTF-8"; // 设置编码格式
    private JSch jsch;
    private Session session;
    Channel channel = null;
    ChannelSftp chSftp = null;
//    sa.url=99.1.36.70
//    sa.port=2222
//    sa.username=ggroot
//    sa.password=ggroot@2016
//    sa.timeout=5000
//    sa.runway=jsch

    //    遍历sa.host配置，依次连接四台服务器，直到获取连接为止
    private String jschHost = "99.1.36.70"  ;
    private int jschPort = 2222;
    private String jschUserName = "ggroot";
    private String jschPassWord = "ggroot@2016" ;
    private int jschTimeOut = 5000;
    private String saRunWay = "jsch";


//    Checking and Ping network
//    Test Env: 99.1.14.110(root/Change@2014)
//    Pro Env: 10.1.251.11（root/netman2007）

    private List<String> resultList=new ArrayList<String>();
    private JschUtil jschUtil = null;

    public JschUtil(){

    }

    public List<String> getResultList() {
        return resultList;
    }

    public void setResultList(List<String> resultList) {
        this.resultList = resultList;
    }

    public JschUtil(String host,int port,String userName,String passWord,int timeOut) {
        this.jschHost = host;
        this.jschPort = port;
        this.jschUserName = userName;
        this.jschPassWord = passWord;
        this.jschTimeOut = timeOut;
    }


    /**
     * 连接到指定的linux服务器
     *
     * @throws com.jcraft.jsch.JSchException
     */
    public boolean connect() throws JSchException {
        jsch = new JSch();// 创建JSch对象
        List<String> hosts = new ArrayList<String>();
        if(jschHost.indexOf("|") > 0){
            hosts.addAll(Arrays.asList(jschHost.split("\\|")));
        }else{
            hosts.add(jschHost);
        }
        boolean result = false;
        for(String host : hosts){
            try{
                long begin = System.currentTimeMillis();
                logger.debug("Try to connect to jschHost = " + jschHost + ",as jschUserName = " + jschUserName + ",as jschPort =  " + jschPort);
                session = jsch.getSession(jschUserName, host, jschPort);// // 根据用户名，主机ip，端口获取一个Session对象
                session.setPassword(jschPassWord); // 设置密码
                Properties config = new Properties();
                config.put("StrictHostKeyChecking", "no");
                session.setConfig(config);// 为Session对象设置properties
                session.setTimeout(jschTimeOut);//设置连接超时时间
                session.connect();
                logger.debug("Connected successfully to jschHost = " + jschHost + ",as jschUserName = " + jschUserName + ",as jschPort =  " + jschPort);
                long end = System.currentTimeMillis();
                logger.debug("Connected To SA Successful in {} ms", (end-begin));
                result = session.isConnected();
            }catch(Exception e){
                logger.error(e.getMessage(), e);
            }finally{
                if(result){
                    logger.debug("success");
                    break;
                }else{
                    logger.debug("failure");
                    continue;
                }
            }
        }
        if(!session.isConnected())
        {
            logger.error("获取连接失败");
        }
        return  session.isConnected();
    }
    public void close()
    {
        if(channel != null && channel.isConnected()){
            channel.disconnect();
            channel=null;
        }
        if(session!=null && session.isConnected()){
            session.disconnect();
            session=null;
        }
    }

    //重载一个返回int returncode的方法
    public int execCmdReturnCode(String command) throws Exception{
        int result = -2;


        logger.debug(command);
        resultList.clear();
        BufferedReader reader = null;

        String res="";
        try {
            channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            channel.setInputStream(null);
            ((ChannelExec) channel).setErrStream(System.err);
            channel.connect();
            InputStream in = channel.getInputStream();
            reader = new BufferedReader(new InputStreamReader(in, Charset.forName(charset)));
            while((res=reader.readLine()) != null)
            {
                resultList.add(res.replaceAll("\t","\n"));
                System.out.println(res);
            }
            StringBuffer sb = new StringBuffer();
            for(String rs:resultList) {
                sb.append(rs.replaceAll(" ","&nbsp;&nbsp;")+"\n");
            }
            result = channel.getExitStatus();
            if(command.indexOf("cat")!=0&&sb.toString().indexOf("[Error]")>0){
                if(result==0||result==-1){
                    result = 1;
                }
            }
            // result=0;
        } catch (IOException e) {
            logger.error(e.getMessage(),e);
        } catch (JSchException e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }

        return result;

    }

    /**
     * 上传文件
     *
     * @param directory 上传的目录,有两种写法１、如/opt，拿到则是默认文件名２、/opt/文件名，则是另起一个名字
     * @param uploadFile 要上传的文件 如/opt/xxx.txt
     */
    public void upload(String directory, String uploadFile) {
        try {
            connect();//建立服务器连接
            logger.debug("Opening Channel.");
            channel = session.openChannel("sftp"); // 打开SFTP通道
            channel.connect(); // 建立SFTP通道的连接
            chSftp = (ChannelSftp) channel;
            File file = new File(uploadFile);
            long fileSize = file.length();

           /*方法一
             OutputStream out = chSftp.put(uploadFile, new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE); // 使用OVERWRITE模式
             byte[] buff = new byte[1024 * 256]; // 设定每次传输的数据块大小为256KB
             int read;
             if (out != null) {
                 logger.debug("Start to read input stream");
                InputStream is = new FileInputStream(directory);
                do {
                    read = is.read(buff, 0, buff.length);
                     if (read > 0) {
                            out.write(buff, 0, read);
                     }
                     out.flush();
                 } while (read >= 0);
                 logger.debug("input stream read done.");
             }*/

//            chSftp.put(uploadFile, directory, new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE); //方法二

            // chSftp.put(new FileInputStream(src), dst, new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE); //方法三
            logger.debug("成功上传文件至"+directory);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            chSftp.quit();

            if (channel != null) {
                channel.disconnect();
                logger.debug("channel disconnect");
            }
            if (session != null) {
                session.disconnect();
                logger.debug("channel disconnect");
            }
        }
    }


    /**
     * 下载文件
     *
     * @param directory 下载的目录,有两种写法１、如/opt，拿到则是默认文件名２、/opt/文件名，则是另起一个名字
     * @param downloadFile 要下载的文件 如/opt/xxx.txt
     *
     */
    public void download(String directory, String downloadFile) {
        try {
            connect();//建立服务器连接
            logger.debug("Opening Channel.");
            channel = session.openChannel("sftp"); // 打开SFTP通道
            channel.connect(); // 建立SFTP通道的连接
            chSftp = (ChannelSftp) channel;
            SftpATTRS attr = chSftp.stat(downloadFile);
            long fileSize = attr.getSize();
//            chSftp.get(downloadFile, directory, new FileProgressMonitor(fileSize)); // 代码段1


            //OutputStream out = new FileOutputStream(directory);
            //chSftp.get(downloadFile, out, new FileProgressMonitor(fileSize)); // 代码段2

            /*代码段3

            InputStream is = chSftp.get(downloadFile, new MyProgressMonitor());
            byte[] buff = new byte[1024 * 2];
            int read;
            if (is != null) {
                logger.debug("Start to read input stream");
                do {
                    read = is.read(buff, 0, buff.length);
                    if (read > 0) {
                        out.write(buff, 0, read);
                    }
                    out.flush();
                } while (read >= 0);
                logger.debug("input stream read done.");
            }*/

            logger.debug("成功下载文件至"+directory);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            chSftp.quit();
            if (channel != null) {
                channel.disconnect();
                logger.debug("channel disconnect");
            }
            if (session != null) {
                session.disconnect();
                logger.debug("channel disconnect");
            }
        }
    }

    /**
     * 删除文件
     * @param deleteFile 要删除的文件
     */
    public void delete(String deleteFile) {

        try {
            connect();//建立服务器连接
            logger.debug("Opening Channel.");
            channel = session.openChannel("sftp"); // 打开SFTP通道
            channel.connect(); // 建立SFTP通道的连接
            chSftp = (ChannelSftp) channel;
            chSftp.rm(deleteFile);
            logger.debug("成功删除文件"+deleteFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public JschUtil getJschUtil() {
        return jschUtil;
    }

    public void setJschUtil(JschUtil jschUtil) {
        this.jschUtil = jschUtil;
    }

    public String getCharset() {
        return charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public static void main(String[] args) throws Exception{
        JschUtil jschUtil = new JschUtil();
        boolean isConnected = false;
        isConnected  = jschUtil.connect();
        String command = "/home/ooflow/scripts/db/GrantDevUser/passwd_create.sh gpfsdb1,liguang-sa.rtitest.com";
        if(isConnected == true){
            if(args!=null && args.length>0){
                command = "";
                for(int i=0;i<args.length;i++){
                    command = command +" " + args[i];
                }
            }

//            String command = args[0];
            System.out.println("返回码" + jschUtil.execCmdReturnCode(command));
            jschUtil.getResultList();
            for(String rs:jschUtil.getResultList()) {
                System.out.println(rs);

            }
            jschUtil.close();

        }


    }
}

